package com.changgou.seckill.multiThread;

import com.alibaba.fastjson.JSON;
import com.changgou.delay.feign.DelayFeign;
import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import com.changgou.seckill.pojo.SeckillOrder;
import com.changgou.seckill.pojo.SeckillStatus;
import entity.IdWorker;
import entity.RedisConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class MultiThreadOrderTask {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;
    @Autowired
    private DelayFeign delayFeign;

    @Value("${mq.delay.delayQueue.seckillorder}")
    private String delayQueue;

    @Async
    public void createOrder() {
        RedisConfig.convertRedisTemplate(redisTemplate);
        //从任务队列中拿取任务
        SeckillStatus seckillStatus = (SeckillStatus) redisTemplate.boundListOps("SeckillOrderQueue").rightPop();
        if (seckillStatus != null) {
            //拿取商品队列中的数据
            Long resultGoodsId = (Long) redisTemplate.boundListOps("SeckillGoodsCountList_" + seckillStatus.getGoodsId()).rightPop();
            if (resultGoodsId == null) {
                //没有库存了
                //清除用户订单数和抢单状态
                clearStatus(seckillStatus);
                return;
            }
            Long goodsId = seckillStatus.getGoodsId();
            String username = seckillStatus.getUsername();
            String time = seckillStatus.getTime();

            //获取商品数据
            SeckillGoods goods = (SeckillGoods) redisTemplate.boundHashOps("SeckillGoods_" + time).get(goodsId.toString());
            //有库存，创建秒杀订单
            SeckillOrder seckillOrder = new SeckillOrder();
            seckillOrder.setId(idWorker.nextId());
            seckillOrder.setSeckillId(goodsId);
            seckillOrder.setMoney(goods.getCostPrice());
            seckillOrder.setUserId(username);
            seckillOrder.setCreateTime(new Date());
            seckillOrder.setStatus("0");

            //将秒杀订单存入redis
            redisTemplate.boundHashOps("SeckillOrder").put(username, seckillOrder);
            //同时添加一个用户名队列方便定时清理时查询
            redisTemplate.boundListOps("UserOrderQueue").leftPush(username);

            //商品库存计数器-1
            Long goodsCount = redisTemplate.boundHashOps("SeckillGoodsCount").increment(goodsId.toString(), -1);
            goods.setStockCount(goodsCount.intValue());

            if (goodsCount <= 0) {
                //商品没有库存
                //同步库存到数据库
                seckillGoodsMapper.updateByPrimaryKeySelective(goods);
                //清除redis中的商品信息
                redisTemplate.boundHashOps("SeckillGoods_" + time).delete(goodsId.toString());
            }

            //抢单成功，更新用户抢单状态
            seckillStatus.setOrderId(seckillOrder.getId());
            seckillStatus.setMoney(Float.valueOf(seckillOrder.getMoney()));
            seckillStatus.setStatus(2); //下单成功
            redisTemplate.boundHashOps("UserQueueStatus").put(username, seckillStatus);

            //最后将订单信息添加到延时消息队列中
            delayFeign.sendMessage(JSON.toJSONString(seckillStatus), delayQueue);
        }
    }

    /****
     * 清理用户排队信息和抢单状态
     * @param seckillStatus
     */
    private void clearStatus(SeckillStatus seckillStatus) {
        redisTemplate.boundHashOps("UserQueueCount").delete(seckillStatus.getUsername());
        redisTemplate.boundHashOps("UserQueueStatus").delete(seckillStatus.getUsername());
    }
}
